package aiku.numericalcontroloa.Service.Impl;

import aiku.numericalcontroloa.Base.Utils.HttpStatus;
import aiku.numericalcontroloa.Base.Utils.Result;
import aiku.numericalcontroloa.Mapper.*;
import aiku.numericalcontroloa.Model.Dto.DevicesReturnDto;
import aiku.numericalcontroloa.Model.Entity.*;
import aiku.numericalcontroloa.Model.Vo.DevicesReturnPageVo;
import aiku.numericalcontroloa.Model.Vo.DevicesReturnVo;
import aiku.numericalcontroloa.Model.Vo.OutboundPartVo;
import aiku.numericalcontroloa.Model.Vo.userDevicesReturnVo;
import aiku.numericalcontroloa.common.utils.DateUtils;
import aiku.numericalcontroloa.enums.RoleEnum;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import aiku.numericalcontroloa.Service.DevicesReturnService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author 马
* @description 针对表【devices_return】的数据库操作Service实现
* @createDate 2024-03-04 15:43:48
*/
@Service
public class DevicesReturnServiceImpl extends ServiceImpl<DevicesReturnMapper, DevicesReturn>
    implements DevicesReturnService{
    @Autowired
    private DevicesReturnMapper devicesReturnMapper;
    @Autowired
    private DevicesOutboundMapper devicesOutboundMapper;
    @Autowired
    private DevicesMapper devicesMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OutboundPartMapper outboundPartMapper;
    @Autowired
    private RemarksMapper remarksMapper;

    @Override
    public Result UserSelectList() {
        //获取userid
        String userid = StpUtil.getLoginId().toString();
        LambdaQueryWrapper<DevicesReturn> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DevicesReturn::getUserId,userid)
                .eq(DevicesReturn::getDeleted,0);
        List<DevicesReturn> devicesReturnList = devicesReturnMapper.selectList(queryWrapper);
        List<userDevicesReturnVo> devicesReturnVoList = new ArrayList<>();
        //如果不为空，拿到所有的returnid
        if(devicesReturnList.isEmpty()){
            return Result.success("查询成功",devicesReturnVoList);
        }
        Map<String, DevicesReturn> returnMap = devicesReturnList.stream().collect(Collectors.toMap(DevicesReturn::getId, Function.identity()));
        List<String> returnIdList = devicesReturnList.stream().map(DevicesReturn::getId).collect(Collectors.toList());
        //拿到申请入库id，查询信息
        List<DevicesOutbound> devicesOutbounds = devicesOutboundMapper.selectList(new LambdaQueryWrapper<DevicesOutbound>().in(DevicesOutbound::getReturnId,returnIdList));
        //通过设备id查询设备信息
        List<String> devicesIdList = devicesOutbounds.stream().map(DevicesOutbound::getDevicesId).collect(Collectors.toList());
        List<Devices> devicesList = devicesMapper.selectList(new LambdaQueryWrapper<Devices>().in(Devices::getId,devicesIdList));
        Map<String, Devices> stringDevicesMap = devicesList.stream().collect(Collectors.toMap(Devices::getId, Function.identity()));

        for (DevicesOutbound outbound : devicesOutbounds) {
            if (outbound.getReturnId()==null){
                continue;
            }
            Devices devices = stringDevicesMap.get(outbound.getDevicesId());

            DevicesReturn aReturn = returnMap.get(outbound.getReturnId());
            userDevicesReturnVo vo = new userDevicesReturnVo();
            BeanUtils.copyProperties(aReturn,vo);
            BeanUtils.copyProperties(outbound,vo);
            BeanUtils.copyProperties(devices,vo);
            vo.setPrice(outbound.getPrice());
            devicesReturnVoList.add(vo);
        }

        return Result.success("查询成功",devicesReturnVoList);
    }

    /**
     * 管理分页查询所有用户借出的设备
     * @param page
     * @param size
     * @param status
     * @return
     */
    @Override
    public Result selectPageList(Integer page, Integer size, String status) {
        //还未做权限
        Page<DevicesReturn> pages = new Page<>(page, size);
        LambdaQueryWrapper<DevicesReturn> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DevicesReturn::getDeleted,0);
        //如果有状态，就查询状态，-1的话就是全部状态
        if (!status.equals("-1") && status!=null){
            queryWrapper.eq(DevicesReturn::getReturnStatus, status);
        }
        List<DevicesReturn> devicesReturnList = devicesReturnMapper.selectPage(pages, queryWrapper).getRecords();
        //如果不为空，拿到所有的returnid
        if(devicesReturnList.size()==0){
            return Result.success(new DevicesReturnPageVo());
        }
        Map<String, DevicesReturn> returnMap = devicesReturnList.stream().collect(Collectors.toMap(DevicesReturn::getId, Function.identity()));
        List<String> returnIdList = devicesReturnList.stream().map(DevicesReturn::getId).collect(Collectors.toList());
        //拿到申请入库id，查询信息
        List<DevicesOutbound> devicesOutbounds = devicesOutboundMapper.selectList(new LambdaQueryWrapper<DevicesOutbound>().in(DevicesOutbound::getReturnId,returnIdList));
        //通过设备id查询设备信息
        List<String> devicesIdList = devicesOutbounds.stream().map(DevicesOutbound::getDevicesId).collect(Collectors.toList());
        if (devicesIdList.size()==0){
            return Result.success(new DevicesReturnPageVo());
        }
        List<Devices> devicesList = devicesMapper.selectList(new LambdaQueryWrapper<Devices>().in(Devices::getId,devicesIdList));
        Map<String, Devices> stringDevicesMap = devicesList.stream().collect(Collectors.toMap(Devices::getId, Function.identity()));

        List<userDevicesReturnVo> devicesReturnVoList = new ArrayList<>();
        for (DevicesOutbound outbound : devicesOutbounds) {
            if (outbound.getReturnId()==null){
                continue;
            }
            Devices devices = stringDevicesMap.get(outbound.getDevicesId());
            DevicesReturn aReturn = returnMap.get(outbound.getReturnId());
            userDevicesReturnVo vo = new userDevicesReturnVo();
            BeanUtils.copyProperties(aReturn,vo);
            BeanUtils.copyProperties(outbound,vo);
            BeanUtils.copyProperties(devices,vo);
            vo.setPrice(outbound.getPrice());
            devicesReturnVoList.add(vo);
        }
        DevicesReturnPageVo pageVo = new DevicesReturnPageVo();
        pageVo.setUserDevicesReturnVoList(devicesReturnVoList);
        pageVo.setTotal(pages.getTotal());
        return Result.success(pageVo);
    }

    /**
     * 管理员审核用户归还产品
     * @param returnId
     * @param status
     * @return
     */
    @Override
    public Result adminCheckReturn(String returnId, String status) {
        //TODO 权限还未做

        //先查询是否借出该产品
        DevicesReturn devicesReturn = devicesReturnMapper.selectById(returnId);
        if(devicesReturn == null){
            return Result.error("没有借出记录");
        }
        //审核通过,就往产品里面加数量
        if (status.equals("0")){
            //拿借出id去申请出库表中拿到数据
            LambdaQueryWrapper<DevicesOutbound> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DevicesOutbound::getReturnId,returnId).eq(DevicesOutbound::getDeleted,0);
            DevicesOutbound devicesOutbound = devicesOutboundMapper.selectOne(wrapper);
            if(devicesOutbound == null){
                return Result.error("出库订单不存在");
            }
            //拿到设备id，修改设备数量
            Devices devices = devicesMapper.selectById(devicesOutbound.getDevicesId());
            if (devices==null){
                return Result.error("产品不存在");
            }
            //修改数量
            devices.setCount(devices.getCount() + devicesOutbound.getCount());
            devicesMapper.updateById(devices);
        }
        devicesReturn.setReturnStatus(status);
        devicesReturnMapper.updateById(devicesReturn);
        return Result.success("操作成功");
    }

    /**
     * 管理员根据id查询借出产品信息
     * @param returnId
     * @return
     */
    @Override
    public Result selectReturnById(String returnId) {
        DevicesReturn devicesReturn = devicesReturnMapper.selectById(returnId);
        if(devicesReturn == null){
            return Result.error("没有借出记录");
        }
        //通过returnId拿到申请入库id，查询信息
        LambdaQueryWrapper<DevicesOutbound> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DevicesOutbound::getReturnId,returnId);
        DevicesOutbound devicesOutbound = devicesOutboundMapper.selectOne(queryWrapper);
        if(devicesOutbound == null){
            return Result.error("没有申请入库记录");
        }
        //拿到设备id，查询设备信息
        Devices devices = devicesMapper.selectById(devicesOutbound.getDevicesId());
        if(devices == null){
            return Result.error("产品不存在");
        }
        userDevicesReturnVo vo = new userDevicesReturnVo();
        BeanUtils.copyProperties(devicesReturn,vo);
        BeanUtils.copyProperties(devices,vo);
        BeanUtils.copyProperties(devicesOutbound,vo);
        vo.setPrice(devicesOutbound.getPrice());
        return Result.success(vo);
    }

    //管理通过模糊查询所有用户借出设备,通过名称,型号,借出人
    @Override
    public Result selectLikeName(String name) {
        //TODO 权限还未做
        LambdaQueryWrapper<Devices> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Devices::getPartName,name).or().like(Devices::getModel,name);
        List<Devices> devicesList = devicesMapper.selectList(queryWrapper);
        List<String> devicesIdList = devicesList.stream().map(Devices::getId).collect(Collectors.toList());
        Map<String, Devices> devicesMap = devicesList.stream().collect(Collectors.toMap(Devices::getId, Function.identity()));
        //拿到设备出库信息
        List<DevicesOutbound> devicesOutboundList = devicesOutboundMapper.selectList(new LambdaQueryWrapper<DevicesOutbound>().in(DevicesOutbound::getDevicesId, devicesIdList));
        List<String> devicesOutboundIdList = devicesOutboundList.stream().map(DevicesOutbound::getReturnId).collect(Collectors.toList());
        Map<String, DevicesOutbound> outboundMap = devicesOutboundList.stream().collect(Collectors.toMap(DevicesOutbound::getReturnId, Function.identity()));
        //拿到设备归还id
        List<DevicesReturn> devicesReturnList = devicesReturnMapper.selectList(new LambdaQueryWrapper<DevicesReturn>().in(DevicesReturn::getId, devicesOutboundIdList));
        List<userDevicesReturnVo> devicesReturnVoList = new ArrayList<>();
        if(devicesReturnList.size()>0){
            for (DevicesReturn aReturn : devicesReturnList) {
                DevicesOutbound outbound = outboundMap.get(aReturn.getId());
                if (outbound==null){
                    continue;
                }

                Devices devices = devicesMap.get(outbound.getDevicesId());
                if (devices==null){
                    continue;
                }
                userDevicesReturnVo userDevicesReturnVo = new userDevicesReturnVo();
                BeanUtils.copyProperties(outbound,userDevicesReturnVo);
                BeanUtils.copyProperties(devices,userDevicesReturnVo);
                BeanUtils.copyProperties(aReturn,userDevicesReturnVo);
                devicesReturnVoList.add(userDevicesReturnVo);
            }
        }
        return Result.success(devicesReturnVoList);
    }

    /**
     * 管理员修改设备归还信息
     * @param devicesReturn
     * @return
     */
    @Override
    public Result adminUpdateDevice(DevicesReturn devicesReturn) {
        //TODO  还未做权限验证
        int i = devicesReturnMapper.updateById(devicesReturn);
        return i>0?Result.success("保存成功"):Result.error(201,"保存失败");
    }

    @Override
    public Result getDevicesReturnList(DevicesReturnDto devicesReturnDto) {
        if (devicesReturnDto == null ||
                (devicesReturnDto.getCurrentPage() == null || devicesReturnDto.getPageSize() == null)){
            return new Result(HttpStatus.BAD_REQUEST,"缺少参数");
        }
        Page<DevicesOutbound> returnPage = new Page<>(devicesReturnDto.getCurrentPage(),devicesReturnDto.getPageSize());

        // 先查询借出记录
        User loginUser = userMapper.selectById(StpUtil.getLoginIdAsString());
        boolean root = loginUser.getRoleId().equals(RoleEnum.ROLE_1.getCodeToString()) ||
                loginUser.getRoleId().equals(RoleEnum.ROLE_5.getCodeToString()) ||
                loginUser.getRoleId().equals(RoleEnum.ROLE_4.getCodeToString());
        LambdaQueryWrapper<DevicesOutbound> devicesOutboundLQW = new LambdaQueryWrapper<>();
        devicesOutboundLQW.orderByDesc(DevicesOutbound::getCreateTime)
                .eq(DevicesOutbound::getType,1)
                .eq(DevicesOutbound::getDeleted,0);
        // 管理员厂长根据申请人查询
        if (root && devicesReturnDto.getUserId() != null){
            devicesOutboundLQW.eq(DevicesOutbound::getUserId,devicesReturnDto.getUserId());
        }else if(!root){
            // 员工查自己的
            devicesOutboundLQW.eq(DevicesOutbound::getUserId,loginUser.getId());
        }
        List<DevicesOutbound> devicesOutboundList = devicesOutboundMapper.selectPage(returnPage, devicesOutboundLQW).getRecords();
        List<DevicesReturnVo> devicesReturnVoList = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        List<String> devicesOutboundIdList = new ArrayList<>();
        if (devicesOutboundList.isEmpty()){
            map.put("total",0);
            map.put("devicesReturnVoList",devicesReturnVoList);
            return Result.success("查询成功",map);
        }else {
            devicesOutboundIdList = devicesOutboundList.stream().map(DevicesOutbound::getId).collect(Collectors.toList());
        }

        // 根据出库id查询出库产品列表
        LambdaQueryWrapper<OutboundPart> outboundPartLQW = new LambdaQueryWrapper<>();
        outboundPartLQW.in(OutboundPart::getOutboundId,devicesOutboundIdList)
                .eq(OutboundPart::getDeleted, 0);  // 0表示未删除;
        List<OutboundPart> outboundPartList = outboundPartMapper.selectList(outboundPartLQW);
        Set<String> devicesIdList = outboundPartList.stream().map(OutboundPart::getPartId).collect(Collectors.toSet());
        List<Devices> devicesList = devicesMapper.selectBatchByIdWithDelete(devicesIdList);
        Map<String, Devices> devicesMap = devicesList.stream().collect(Collectors.toMap(Devices::getId, d -> devicesList.stream()
                .filter(devices -> devices.getId().equals(d.getId()))
                .findFirst()
                .orElse(null)));
        // 根据出库订单id获取出库产品列表
        Map<String,List<OutboundPartVo>> outboundPartMap = new HashMap<>();
        for (OutboundPart outboundPart : outboundPartList){
            Devices devices = devicesMap.get(outboundPart.getPartId());
            OutboundPartVo outboundPartVo = new OutboundPartVo();
            BeanUtils.copyProperties(outboundPart,outboundPartVo);
            outboundPartVo.setPartName(devices.getPartName());
            outboundPartVo.setIsProduct(devices.getIsProduct());
            outboundPartVo.setModel(devices.getModel());
            outboundPartVo.setPrice(devices.getPrice());
            outboundPartVo.setImage(devices.getImage());
            outboundPartVo.setDevicesDescribe(devices.getDevicesDescribe());
            outboundPartVo.setRemark(devices.getRemark());
            if (outboundPartMap.containsKey(outboundPart.getOutboundId())){
                outboundPartMap.get(outboundPart.getOutboundId()).add(outboundPartVo);
            }else {
                List<OutboundPartVo> outboundPartVoList = new ArrayList<>();
                outboundPartVoList.add(outboundPartVo);
                outboundPartMap.put(outboundPart.getOutboundId(),outboundPartVoList);
            }
        }

        // 根据id集合查询归还表
        List<DevicesReturn> devicesReturnList = devicesReturnMapper.selectBatchByOutboundId(devicesOutboundIdList,devicesReturnDto.getReturnStatus());
        if (devicesReturnList.isEmpty()){
            map.put("total",0);
            map.put("devicesReturnVoList",devicesReturnVoList);
            return Result.success("查询成功",map);
        }
        // 查询申请人
        Set<String> userIdList = devicesReturnList.stream().map(DevicesReturn::getUserId).collect(Collectors.toSet());
        List<User> userList = userMapper.selectBatchByIdWithDelete(userIdList);
        Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));

        for (DevicesReturn devicesReturn : devicesReturnList){
            User user = userMap.get(devicesReturn.getUserId());
            outboundPartMap.get(devicesReturn.getDevicesOutboundId());
            DevicesReturnVo devicesReturnVo = new DevicesReturnVo();
            BeanUtils.copyProperties(devicesReturn,devicesReturnVo);
            devicesReturnVo.setNickName(user.getNickName());
            devicesReturnVo.setOutboundPartVoList(outboundPartMap.get(devicesReturn.getDevicesOutboundId()));
            if (devicesReturn.getReturnTime() != null){
                devicesReturnVo.setReturnTime(DateUtils.YMDHMSFormat(devicesReturn.getReturnTime()));
            }
            devicesReturnVoList.add(devicesReturnVo);
        }
        map.put("total",devicesReturnList.size());
        map.put("devicesReturnVoList",devicesReturnVoList);
        return Result.success("查询成功",map);
    }

    @Override
    @Transactional
    public Result addDevicesReturn(DevicesReturnDto devicesReturnDto) {
        if (devicesReturnDto == null ||
                (devicesReturnDto.getId() == null || devicesReturnDto.getId().isEmpty())){
            return new Result(HttpStatus.BAD_REQUEST,"缺少参数");
        }

        // 查询是否有该归还申请
        DevicesReturn devicesReturn = devicesReturnMapper.selectById(devicesReturnDto.getId());
        if (devicesReturn == null){
            return new Result(HttpStatus.BAD_REQUEST,"该归还申请不存在");
        }
        // 设置归还类型
        devicesReturn.setReturnType(devicesReturnDto.getReturnType());
        // 设置质量状态
        devicesReturn.setQualityStatus(devicesReturnDto.getQualityStatus());
        // 设置归还时间
        devicesReturn.setReturnTime(new Date());
        // 将归还状态设为待审核
        devicesReturn.setReturnStatus("1");
        // 更新数据
        devicesReturnMapper.updateById(devicesReturn);
        // 更新出库产品列表
        outboundPartMapper.updateBatchById(devicesReturnDto.getOutboundPartVoList());

        // 备注
        if (devicesReturnDto.getRemark() != null){
            Remarks remarks = new Remarks();
            remarks.setQueryId(devicesReturn.getId());
            remarks.setRemarkContent(devicesReturnDto.getRemark());
            remarksMapper.insert(remarks);
        }
        return Result.success("申请成功");
    }

    @Override
    public Result examineDevicesReturn(DevicesReturnDto devicesReturnDto) {
        if (devicesReturnDto == null || devicesReturnDto.getId() == null || devicesReturnDto.getId().isEmpty()){
            return new Result(HttpStatus.BAD_REQUEST,"缺少参数");
        }
        // 查询是否有该归申请
        DevicesReturn devicesReturn = devicesReturnMapper.selectById(devicesReturnDto.getId());
        if (devicesReturn == null){
            return new Result(HttpStatus.BAD_REQUEST,"该归还申请不存在");
        }
        devicesReturn.setReturnStatus(devicesReturnDto.getReturnStatus());
        LambdaUpdateWrapper<DevicesReturn> devicesReturnLUW = new LambdaUpdateWrapper<>();
        devicesReturnLUW.eq(DevicesReturn::getId,devicesReturn.getId())
                .set(DevicesReturn::getReturnStatus,devicesReturnDto.getReturnStatus());
        // 更新数据
        devicesReturnMapper.update(null,devicesReturnLUW);

        if (devicesReturn.getReturnStatus().equals("0")){
            // 申请通过，仓库中的数量相应增加
            // 根据出库id查询出库产品表
            LambdaQueryWrapper<OutboundPart> outboundPartLQW = new LambdaQueryWrapper<>();
            outboundPartLQW.eq(OutboundPart::getOutboundId,devicesReturn.getDevicesOutboundId());
            List<OutboundPart> outboundPartList = outboundPartMapper.selectList(outboundPartLQW);
            // 根据partIdList查询产品
            List<String> partIdList = outboundPartList.stream().map(OutboundPart::getPartId).collect(Collectors.toList());
            List<Devices> devicesList = devicesMapper.selectBatchByIdWithDelete(partIdList);
            Map<String, Devices> devicesMap = devicesList.stream().collect(Collectors.toMap(Devices::getId, Function.identity()));
            List<Devices> newDevicesList = new ArrayList<>();
            for (OutboundPart outboundPart : outboundPartList){
                Devices devices = devicesMap.get(outboundPart.getPartId());
                // 归还数量
                outboundPart.setReturnCount(outboundPart.getOutboundCount());
                devices.setCount(devices.getCount()+outboundPart.getReturnCount());
                newDevicesList.add(devices);
            }
            // 更新数据
            devicesMapper.updateCountBatchById(newDevicesList);
            outboundPartMapper.updateBatchById(outboundPartList);
        }
        return Result.success("操作成功");
    }

    @Override
    public Result deleteReturn(DevicesReturnDto devicesReturnDto) {
        if (devicesReturnDto == null || devicesReturnDto.getId() == null || devicesReturnDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查权限，只有管理员有权
        User user = userMapper.selectById(StpUtil.getLoginIdAsString());
        if (!user.getRoleId().equals(RoleEnum.ROLE_1.getCodeToString())) {
            return new Result(HttpStatus.FORBIDDEN, "权限不足");
        }

        // 删除
        UpdateWrapper<DevicesReturn> outboundPartUpdateWrapper = new UpdateWrapper<>();
        outboundPartUpdateWrapper.eq("id",devicesReturnDto.getId())
                .set("deleted",1); // 设置删除状态为已删除;
        devicesReturnMapper.update(null,outboundPartUpdateWrapper);

        return Result.success("删除成功");
    }

}




